package Analizer;

import java.awt.AWTException;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.Image;
import java.awt.MouseInfo;
import java.awt.Point;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Vector;

import javax.swing.JPanel;

import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.mouse.NativeMouseEvent;
import org.jnativehook.mouse.NativeMouseListener;
import org.jnativehook.mouse.NativeMouseMotionListener;



/**
 * @author Tomek2
 *
 */
public class Analizer extends i_OknoAnalizer implements Serializable {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 2L;
	/**
	 * 
	 */
	private globEvent ae;
	private  _A_Path pathSchem;
	public static String _PatchZapisuSchematu;

	public Analizer() throws IOException {
		super();
		pathSchem = new _A_Path();
		_PatchZapisuSchematu = pathSchem.iGlobalPath +pathSchem.iKatSys + "/SCHEMATY.csv";
		
		
		iLadujZPlikuSchemat( _PatchZapisuSchematu );
		
		{
			panel.setBounds(10, 217, 156, 33);
			getContentPane().add(panel);
		}
		//keyboard_hook-0.3
		//http://kra.lc/blog/2011/07/java-global-system-hook/
		try {
			GlobalScreen.registerNativeHook();
		} catch (NativeHookException ex) {
            System.err.println("There was a problem registering the native hook.");
            System.err.println(ex.getMessage());
            System.exit(1);
		}
		
		 System.out.println("Hook state: "+ GlobalScreen.isNativeHookRegistered());

		
		ae = new globEvent();
        GlobalScreen.getInstance().addNativeMouseListener(ae);
        GlobalScreen.getInstance().addNativeMouseMotionListener(ae);
        //GlobalScreen.getInstance().addNativeKeyListener(ae);
	}
	
	//START STOP
	/**
	 * @param i_start_Stop generuje klawisz PLAY/STOP true pracuje
	 * @param i_nagrywaj generuje false jesli nie nagrywac
	 */
	private boolean i_start_Stop = false; // if false to stop
	boolean i_nagrywaj = false; // nie nagrywa
	@Override
	public void if_StartStop() {
		// TODO Auto-generated method stub
		i_start_Stop = !i_start_Stop;
		if (i_start_Stop == false){
			i_nagrywaj = false;
			ic_StartStop.setText("play");
		}
		else { 
			ic_StartStop.setText("stop"); 
			i_nagrywaj= true;}
		System.out.println(i_start_Stop);			
	}
	
	
	@Override
	public void if_Odtworz(int iPozycjaListySchem) throws AWTException {
		if (i_start_Stop == true) return;
		if (iVSchemList.isEmpty()) {
			System.out.println("i_Odtworz Brak pozycji do  odtworzenia");
			return;
		}
		if (iPozycjaListySchem > iVSchemList.size()){
			System.out.println("i_Odtworz zbyt wysoka pozycja do odtworzenia " + iVSchemList.size() +" pozycji masz do wyboru");
			return;
		}
		
		System.out.println("i_Odtworz odtwarzam pozycja " + iPozycjaListySchem);
		MouseMove_TM mm = new MouseMove_TM(this.iVSchemList);
		
		iElement i_El = iVSchemList.get(iPozycjaListySchem);
		//mm.iMouseMove(0, 0, 700, 700, iPozycjaListySchem, 2500);;
		mm.iMouseMove(700, 700,  3700, false);;

	}
	
	private int i_valSpinner;
	@Override
	public void if_Spinner() {
		i_valSpinner = (int) ic_spinner.getValue();
			System.out.println("i_spinner - " + i_valSpinner);
	}
	
	@Override
	public void if_Rysuj(Image img) {
		// TODO Auto-generated method stub	
	}
		
	
	public int i_odcinek;
	private int i_Xtemp;
	private int i_Ytemp;
	
	@Override
	public boolean if_Odcinek (){
		Point point = MouseInfo.getPointerInfo().getLocation();
		i_odcinek += Math.sqrt( Math.pow( (Math.abs (i_Xtemp - point.x)), 2) + Math.pow( (Math.abs (i_Ytemp - point.y)), 2) );
		i_Xtemp = point.x;
		i_Ytemp = point.y;
		ic_dlRuchu.setText("" + i_odcinek);
 		return true;
	}
	
	private long i_speed;
	private long i_TotalTimes;
	private long itmp, itmp2;
	public final JPanel panel = new JPanel();
	
	@Override
	public boolean if_Speed() 
	{
		//reset
		if (System.currentTimeMillis()-itmp >= 1000){
			//System.out.println ("resret licz");
			itmp2 = System.currentTimeMillis();
			if_newKrzywa("resetuj");
		}
		
		itmp = System.currentTimeMillis();
		if (System.currentTimeMillis() - itmp2 >= i_valSpinner) {
			i_speed = System.currentTimeMillis() - itmp2;
			ic_speed.setText(""+ i_speed);
			if_newKrzywa("wpisz");
			//System.out.println("szybkosc " + i_speed);
			itmp2 = System.currentTimeMillis();
			i_odcinek = 0;
			return true;
		}
		return false;
	}
	
	/** 
	 * Dodaje do lisy sechmaty 
	 */
	private iElement i_e;
	
	@Override
	public void if_addSchemToList(Vector i_Krzywa) {
		//wpis do Vectora
		iVSchemList.add(new iElement(i_Krzywa));
		System.out.println("Wielkosc listy vectora"+ iVSchemList.size());
		i_iOdswiezListeandPanel();
	}
	
	/* (non-Javadoc)
	 * @see MouseAnalizer.iInterf_Onko#i_iOdswiezListeandPanel()
	 */
	public void i_iOdswiezListeandPanel(){
		//wpis do panela
	    GridBagConstraints gbc = new GridBagConstraints();
	    gbc.gridwidth = GridBagConstraints.REMAINDER;
	    gbc.anchor = GridBagConstraints.FIRST_LINE_END;
	    gbc.weightx = 1;
	    gbc.fill = GridBagConstraints.HORIZONTAL;
	    
	    i_PanelSchemLista.removeAll();
	    
	    for(int poz = 0; poz < iVSchemList.size(); poz ++){
	    	i_e = iVSchemList.get(poz);
	    	i_PanelSchemLista.add(i_e, gbc, 0);
	    }
	    
	    {
	    	if (iVSchemList.isEmpty()){
	    		i_SizeSchem.setText("-" +" lp.");
	    		snm.setMaximum(0);
	    	} else 	{
	    		i_SizeSchem.setText("" + iVSchemList.size() + " lp.");
	    		snm.setMaximum(iVSchemList.size());
	    		snm.setValue(1);
	    		snm.setMinimum(1);
	    	}
	    }

		revalidate();
		repaint();
	}
	
	@Override
	public boolean if_isTime(long i_oldtime, int i_expectedTime) {
		// TODO Auto-generated method stub
		return false;
	}
	

	class globEvent implements NativeMouseMotionListener, NativeMouseListener 
	{
		@Override
		public void nativeMouseDragged(NativeMouseEvent arg0) {}
		@Override
		public void nativeMouseMoved(NativeMouseEvent arg0) {
			if (!i_start_Stop) return;
			if_Speed();
			if_Odcinek ();			
		}
		@Override
		public void nativeMouseClicked(NativeMouseEvent arg0) {}
		
		@Override
		public void nativeMousePressed(NativeMouseEvent arg0) {
			if (!i_start_Stop) return;
			
			//System.err.println("Wpis do listy krzywych");
			if(i_TotalTimes <100)return;
			if_addSchemToList (i_Krzywa);
			i_Krzywa = null;
			i_TotalTimes = 0;
	}
				
		@Override
		public void nativeMouseReleased(NativeMouseEvent arg0) {}
	}
	


	public void if_newKrzywa(String p){
		if (i_Krzywa == null) {	i_Krzywa = new Vector<i_Punkt>(); }
		
		switch(p){
		case "resetuj":
			System.err.println("Resetuje krzywa");
			i_Krzywa=null;
			break;
		case "wpisz":
			System.err.println("wpisuje");
			this.i_TotalTimes += i_speed;
			i_Krzywa.add(new i_Punkt(i_Xtemp, i_Ytemp, i_speed, i_odcinek));
			break;		
		}
	}
	/**
	 * SAVE READ OBJECT
	 * @see
	 * http://beginwithjava.blogspot.com/2011/04/java-file-save-and-file-load-objects.html
	 * http://stackoverflow.com/questions/12469376/storing-2d-array-into-a-file
	 */
	private FileOutputStream saveFile;
	private ObjectOutputStream save;
	iElement i_El;

		
		 
	
	private String iSciezka() throws IOException{
		
		return pathSchem.iGlobalPath + pathSchem.iKatSys + "A001_SCHEMATY_MYSZY/";
		
	}

	
	public boolean iZapiszDoPlikuSchemat() throws IOException{
		String folder = iSciezka();
		System.out.println("ZAPISUJE SCHEMATY: \n" + folder);
		
		ArrayList<iDANE> dane = new ArrayList<iDANE>();
		
		if (!iVSchemList.isEmpty())
			i_El = iVSchemList.get(i_SpinnerSchemListValue);
			else {
				System.err.println("Nie ma schematow");
				return false;
				}	
		// Serialize
		//http://stackoverflow.com/questions/1321988/finding-serialversionuid-of-serialized-object
		Iterator<iElement> it = iVSchemList.iterator();
		
		
		long lp=1;
		

		while (it.hasNext()){	
			try {
				iElement el = it.next();
				
				dane.add(new iDANE(el.iKrzywa,el.iTotalTimesKrzywej,el.iDlKrzywa));
				
				saveFile = new FileOutputStream(folder+"0000"+lp+"-schem.sav");
				save = new ObjectOutputStream(saveFile);
				save.writeObject(el);
				
				
			} catch (IOException e) {
				e.printStackTrace();
			} finally{
				save.close();
			}

			lp++;
		}
		
		//http://stackoverflow.com/questions/20358171/last-fm-java-lang-classcastexception-reading-in-user-objects-from-file
		try{

	        FileOutputStream fout = new FileOutputStream(folder +"SCHEMATY.csv");
	        ObjectOutputStream oos = new ObjectOutputStream(fout);   
	        oos.writeObject(dane);
	        oos.close();
	        System.out.println("SCHEMATY.csv");

	       }catch(Exception ex){
	           ex.printStackTrace();
	       }
		
		
		
		
		return true;
	}
	
	public ArrayList<iDANE> iLadujZPlikuSchemat(String folder){

		System.out.println("ODCZYTUJE SCHEMATY: \n" + folder);

/*		File[] files;
		files = new File(folder).listFiles(new FileFilter() {
		    @Override
		    public boolean accept(File file) {
		        return !file.isHidden();
		    }
		});
		if(files==null){
			System.out.println("Brak elementow)");
			return null;
		}
		
		FileInputStream File = null;
		ObjectInputStream Load = null;
		iVSchemList.clear();

		for (File file:files){
			
			try {
				File = new FileInputStream(""+file);
				Load = new ObjectInputStream(File);
				iVSchemList.add((iElement) Load.readObject());
				Load.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}*/
		
		
		ArrayList<iDANE> id = null;
		ObjectInputStream in;
		
		    String fileName = "SCHEMATY.csv";
		    try{
		    in = new ObjectInputStream(new FileInputStream(folder+fileName));
		    }catch(IOException e){
		    	return null;
		    }

		    try{
		    id =  (ArrayList<iDANE>) in.readObject();
		    }catch(IOException | ClassNotFoundException e){
		    	
		      e.printStackTrace();
		      return null;
		    } finally {
		    try {
				in.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		    }
		
		
		i_iOdswiezListeandPanel();
		
		//System.out.println("Dane size " + id.size());
		//System.out.println(id.get(1).iCzasKrzywej);
		
		return id;
	}
	
	public boolean iUsunSchemat(){
		return true;
	}

	
	
	


	
	
	
	
	
	
	
	
	
	
	
	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Analizer frame = new Analizer();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}
}
